﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace _06_await和async
{
    // async 和 await  是异步代码实现的简单形式
    // async 和 await 是对 Task 操作的语法糖 

    // async 和 await 必须搭配起来使用 
    // await 必须写在有 async 修饰的函数内部
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {

        }

        private async void button1_Click(object sender, EventArgs e)
        {
            Task task = Task.Run(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("这是一个异步任务");
            });
            //task.Wait(); // 等待异步任务执行完成 
            await task; // 等待异步任务执行完成 
            Console.WriteLine("-------------------------");
        }

        private async void button2_Click(object sender, EventArgs e)
        {
            Task<int> task = Task.Run(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("这是一个异步任务");
                return 100;
            });
            //task.Wait();
            //Console.WriteLine(task.Result); // 使用 result 形式获取结果 

            // await 可以阻塞线程 也可以获取结果
            // 使用 await 获取结果 
            int num = await task; // 也可以获取结果
            Console.WriteLine($"{num}");
        }

        private async void button3_Click(object sender, EventArgs e)
        {
            //AsyncFun(); // 返回值为void的async 函数不能使用await 
            //Console.WriteLine("不会等待上面的任务执行完成");

            await AsyncFun1(); // async 修饰的函数返回值是task 的话 可以使用 await 等待任务结果
            int a = await AsyncFun2(); // async 修饰的函数返回值是task 的话 可以使用 await 等待任务结果
            Console.WriteLine("会等待上面的任务执行完成");
        }

        public async void AsyncFun()
        {
            //return 1;

            //async  修饰的函数只能有三种返回值 void Task,task<T>
            await Task.Run(() =>
             {
                 Thread.Sleep(1000);
                 Console.WriteLine("这是一个异步");
             });

        }

        public async Task AsyncFun1()
        {
            //return 1;

            //async  修饰的函数只能有三种返回值 void Task,task<T>
            Task task = Task.Run(() =>
            {
                Thread.Sleep(1000);
                Console.WriteLine("这是一个异步");
            });
            await task;
            //return; // 因为异步任务没有结果返回 因此不需要返回任何内容 

            // async 修饰的方法本身的返回结果就是 Task 

            // 返回值Task 指的是AsyncFun1整体的异步函数 
        }

        // 使用async 创建一个异步任务 异步任务返回的结果是 int 类型
        // async 修饰的方法本身就是一个异步任务 和 new Task 的到的结果是一样的 
        // 因此在修饰函数返回值是 一定要加上 Task  如果不需要Task 实例对象则 直接写void 
        public async Task<int> AsyncFun2()
        {
            Task<int> task = Task.Run(() => { return 1; });

            //return  task; // task 的类型是 Task<int> 而我们需要的类型是 int 类型 
            return await task; // await task 获取结果放在return 后面
        }
    }
}
